package com.wisdytech.common.thrift.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.wisdytech.common.bean.event.DcsEquipEvent;
import com.wisdytech.common.bean.event.DcsParamChangeEvent;
import com.wisdytech.common.bean.event.DcsParamEvent;
import com.wisdytech.common.enums.ActionType;
import com.wisdytech.common.thrift.api.DCSService;
import com.wisdytech.common.thrift.dto.EquipmentPARAM;
import com.wisdytech.common.thrift.dto.Param;
import com.wisdytech.common.thrift.dto.ServerDto;
import com.wisdytech.common.thrift.service.IEquipmentCollectionInfoService;
import com.wisdytech.common.utils.BaseUtil;
import com.wisdytech.linkdcs.equipment.dao.IEqClientDao;
import com.wisdytech.linkdcs.equipment.dao.IEqCollectionParamDao;
import com.wisdytech.linkdcs.equipment.dao.IEqEquipmentDao;
import com.wisdytech.linkdcs.equipment.dao.IEqToClientDao;
import com.wisdytech.linkdcs.equipment.model.CollectionParam;
import com.wisdytech.linkdcs.equipment.model.EquipmentToClient;

@Service
public class EquipmentCollectionInfoServiceImpl implements IEquipmentCollectionInfoService {
	
	private static Logger logger  =LoggerFactory.getLogger(EquipmentCollectionInfoServiceImpl.class);
    
    /**
     * 注入设备dao
     */
    @Resource
    private IEqEquipmentDao equipmentDao;
    
    @Resource
    private IEqCollectionParamDao collectionParamDao;
    

    @Resource
    private IEqClientDao clientDao;
    
    @Resource
    private IEqToClientDao eqToClientDao;
    
    /**
     * 推送信息至DCS
     * @param eqToClientId 设备与采集终端连接
     * @param eqCode 设备编码
     * @param cType 采集方式
     * @param params 采集参数
     * @param type 操作方式
     * @param createTime 创建时间戳
     * @param frequency 采集频率
     * @param address 设备采集地址
     * @param plcProtocal plc采集协议
     * @param fileLockType 文件锁类型
     * @param isDelFile 是否删除
     * @param server 服务器地址
     * @return
     */
    private boolean sentListToDCS(String eqToClientId, String eqCode,int cType,
            List<Param> params,ActionType type,long createTime,int frequency,String address,
            String plcProtocal,String fileLockType,int isDelFile,ServerDto server){
        TTransport tTransport = null;
        try {
            tTransport = new TSocket(server.getIp(),server.getPort());
            tTransport.open();
            TProtocol protocol=new TBinaryProtocol(tTransport);
            DCSService.Client client =new DCSService.Client(protocol);

            client.putEquipmentCollectionInfo(eqToClientId, eqCode, cType, params, type.getCode(), 
            		createTime, frequency, address, plcProtocal, fileLockType, isDelFile);
            
           
            return true;
            
        } catch (TTransportException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (TException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            if(null != tTransport){
                tTransport.close();
            }
        }
        return false;
    }
    
    /**
     * 根据参数拼接出dcs param对象
     * @param type 采集方式
     * @param param 参数对象
     * @return
     */
    public Param getTypeMapObject(int type,CollectionParam param){
		
    	Param params =new Param();
		//参数id
		params.setPARAM_ID(param.getPkId());
		//参数类型
		params.setPARAM_Type(param.getDataType());
		//参数名称
		params.setPARAM_NAME(param.getParamName());
		params.setParamCode(param.getParamCode());
		//缩放比例
		params.setZoom(param.getEnlargeNum());
		params.setParam_Definition(
				Integer.parseInt(param.getParamType()));
		params.setData_Length(param.getDataLength());
		params.setDecimal_Pos(param.getDecimalPos());
		params.setAlarmcode(param.getAlarmCode());
		params.setParam_Field(param.getParamField());
		switch(type) {
		case 1://plc
			params.setParam_Address(param.getPlcAddr());
			break;
		case 2://文件
			params.setParam_Address(param.getFileColumn());
			params.setFile_type(param.getFileType());
			params.setIgnore_first_line(Integer.parseInt(param.getFileIgnoreFirst()));
			break;
		case 3://数据库
			params.setParam_Address(param.getDatabaseParamAddr());
			break;
		case 4://上位机
			params.setParam_Address(param.getUpperParamField());
			params.setParam_Definition(Integer.parseInt(param.getUpperDefinition()));
			break;
		}
		
		return  params;
	}
    
    /**
	 * 根据设备id查找
	 * @param type 类型
	 * @param equipmentId 设备id
	 * @return 
	 */
	public List<Param> getTypeMapObjectLists(int type,String equipmentId){

		List<CollectionParam>  cps =
				collectionParamDao.selectParamByEqId(equipmentId, String.valueOf(type));
		List<Param> eps =new ArrayList<Param>();
		
		for(CollectionParam param : cps) {
			eps.add(getTypeMapObject(type, param));
		}
		
		return eps;
	}
	
	public boolean doDetail(EquipmentToClient  etc,ActionType methodType) {
		
		
		ServerDto server = BaseUtil.getServerAddress(etc.getClientRoute());
        if(null == server){
            return false;
        }
        
        //获取参数对象
        List<Param>  params =
        		getTypeMapObjectLists(etc.getType(), etc.getEquipId());
        
        return sentListToDCS(etc.getPkId(), etc.getEquipCode(), etc.getType(), params, methodType, System.currentTimeMillis(), 
        		etc.getFrequency(), etc.getAddress(), 
        		etc.getPlcProtocal(), etc.getFileLockType(), etc.getIsDelFile(), server);
        
	}
	

	public void doParamDetail(CollectionParam param,String collectionClientId,ActionType actionType) {
		
		int type =Integer.parseInt(param.getCollectionType());
		//查找设备类型下全部关联终端
		
		List<EquipmentToClient>  etcs =eqToClientDao.selectByCollectionClientId(collectionClientId);
		
		//推送指定的参数修改
		Param  ep =getTypeMapObject(type, param);
		List<Param> params =new ArrayList<>();
		params.add(ep);
		
		for(EquipmentToClient etc : etcs ) {
			ServerDto server = BaseUtil.getServerAddress(etc.getClientRoute());
	        if(null == server){
	            continue;
	        }
	        sentListToDCS(etc.getPkId(), etc.getEquipCode(), etc.getType(), params, actionType, 
	        		System.currentTimeMillis(), 
	        		etc.getFrequency(), etc.getAddress(), 
	        		etc.getPlcProtocal(), etc.getFileLockType(), etc.getIsDelFile(), server);
	        
		}
	}

	
	/****设备参数推送事件***/
	/***
	 * 设备终端关联时推送
	 * @param dcsParamEvent
	 */
	@Async
	@EventListener
    public void paramEventListener(DcsParamEvent dcsParamEvent) {
		ActionType methodType= dcsParamEvent.getActionType();
		EquipmentToClient etc =dcsParamEvent.getClientConnect();
		doDetail(etc, methodType);
		
		
	}
	
	/***
	 * 参数单独修改时推送
	 * @param dcsParamEvent
	 */
	@Async
	@EventListener
    public void paramChangeEventListener(DcsParamChangeEvent dcsParamEvent) {
		CollectionParam param =dcsParamEvent.getParam();
		ActionType  actionType =dcsParamEvent.getActionType();
		String collectionClientId =dcsParamEvent.getCollectionClientId();
		doParamDetail(param, collectionClientId, actionType);
	}

}
